package com.neosavvy.grid{
    import com.neosavvy.grid.event.PickFilterGridEvent;
    import com.neosavvy.grid.renderer.CenteredCheckBoxHeaderRenderer;
    import com.neosavvy.grid.renderer.CenteredCheckBoxItemRenderer;

    import mx.collections.ArrayCollection;
    import mx.collections.Sort;
    import mx.collections.SortField;
    import mx.core.ClassFactory;
    import mx.core.UIComponent;

    public class PickFilterGrid extends AutoFilteringGrid {

        private var bPreSelectedIndicesChanged:Boolean = false;
        private var _preSelectedIndices:ArrayCollection;
        private var _selected:Boolean = false;

        private function toggleRowsByPreselectedIndices( ):void {
            var rowsToMarkSelected:ArrayCollection = new ArrayCollection();
            for each (var idx:Number in _preSelectedIndices)
            {
                var pickFilterRow:PickFilterRow = dataProvider.getItemAt(idx) as PickFilterRow;
                if (pickFilterRow)
                    rowsToMarkSelected.addItem(pickFilterRow);
            }


            for each (var row:PickFilterRow in rowsToMarkSelected)
            {
                trace("Setting row as selected " + row.toString() + " as " + _selected);
                row.selected = _selected;
                updatePickFilterRow(row);
            }
        }

        override protected function commitProperties():void {

            addEventListener(PickFilterGridEvent.ITEM_SELECTED, handleItemSelected);
            setDefaultSort();

            if (bPreSelectedIndicesChanged)
            {
                toggleRowsByPreselectedIndices();
                bPreSelectedIndicesChanged = false;
                setDefaultSort();
            }


            super.commitProperties();
        }



        /**
         * This value is used to help the selection checkbox column
         * know which value to retrieve from the proxied data set.
         *
         * By default selected is added to the data set, but if there
         * is some other value coming back from the database it can be
         * used instead
         */
        private var _selectedColumnDatafield:String = "selected";

        private var _applyDefaultSort:Boolean = false;

        private var _enabledSelectAll:Boolean = true;

        public function PickFilterGrid() {
            super();

            /**
             * Note that turning off sortExpertMode will break
             * the select all feature so it must remain on at all times
             */
            this.sortExpertMode = true;
        }

        /**
         * Note that turning off sortExpertMode will break
         * the select all feature so it must remain on at all times
         */
        override public function set sortExpertMode(value:Boolean):void {
            trace("Ignoring request to set sortExpertMode: " + value);
            trace("Disabling this will break the select all feature");
            super.sortExpertMode = true;
        }

        override public function set dataProvider( value:Object):void {
            var arrayCollection:ArrayCollection = new ArrayCollection();
            for each ( var obj:Object in value ) {
                arrayCollection.addItem(new PickFilterRow(false, obj))
            }
            _selected = false;
            _selectedNonProxiedItems = new ArrayCollection();
            super.dataProvider = arrayCollection;

        }

        /***
         *
         * This method will always add the select column with
         * a CenteredCheckBoxItemRenderer to the front of the columns
         * array
         *
         * <grid:AutoFilteringGridColumn
         *    enabledByDefault="true"
         *    autoFilterEnabled="false"
         *    dataField="selected"
         *    headerText="Sel"
         *    itemRenderer="com.neosavvy.grid.renderer.CenteredCheckBoxItemRenderer"
         *    removable="false"/>
         * @param value
         */
        override public function set columns( value:Array ):void {

            var selectColumn:AutoFilteringGridColumn = new AutoFilteringGridColumn();
            selectColumn.enabledByDefault = true;
            selectColumn.autoFilterEnabled = false;
            selectColumn.dataField = _selectedColumnDatafield;
            selectColumn.itemRenderer = new ClassFactory(CenteredCheckBoxItemRenderer);
            selectColumn.headerRenderer = new ClassFactory(CenteredCheckBoxHeaderRenderer);
            selectColumn.removable = false;
            selectColumn.width = 30;
            selectColumn.adjustColumnWidth = false;

            value.splice(0,0,selectColumn);

            super.columns = value;

        }

        override public function resetFilters():void
        {
            super.resetFilters();
            setDefaultSort();
        }

        public function setDefaultSort():void {
            if( _applyDefaultSort ) {
                var sort:Sort = new Sort();
                var sortField:SortField = new SortField();
                sortField.name = _selectedColumnDatafield;
                sortField.descending = true;

                var sortField1:SortField = new SortField();
                sortField1.name = getSecondarySortColumnName();
                sortField.descending = true;

                sort.fields = [sortField, sortField1];
                if ( dataProvider ) {
                    dataProvider.sort = sort;
                    dataProvider.refresh();
                }
            }
        }

        override public function searchWrappedFilterFunction(item:Object):Boolean {

            var isItemSelected:Boolean = false;
            if( item.hasOwnProperty(_selectedColumnDatafield) ) {
                isItemSelected = item[_selectedColumnDatafield] as Boolean;
            }

            if( super.searchTextControl != null )
                return super.searchWrappedFilterFunction(item) || isItemSelected;
            else
                return super.filterFunction(item) || isItemSelected;
            
        }

        protected function getSecondarySortColumnName():String {

            var columns:Array = this.columns;
            for each ( var column:AutoFilteringGridColumn in columns ) {
                if ( column.dataField == _selectedColumnDatafield ) {
                    continue;
                }
                else {
                    return column.dataField;
                }
            }
            return "";
        }

        private var _selectedNonProxiedItems:ArrayCollection = new ArrayCollection();


        public function get selectedNonProxiedItems():ArrayCollection {
            return _selectedNonProxiedItems;
        }

        public function set selectedNonProxiedItems(value:ArrayCollection):void {
            _selectedNonProxiedItems = value;
        }

        private function updatePickFilterRow(pickFilterRow:PickFilterRow):void {
            if (pickFilterRow.selected)
            {
                _selectedNonProxiedItems.addItem(pickFilterRow.wrappedObject);
            }
            else
            {
                var index:int = _selectedNonProxiedItems.getItemIndex(pickFilterRow.wrappedObject);
                trace("Found item in selected Non proxied items at: " + index);
                if ( index >= 0)
                    _selectedNonProxiedItems.removeItemAt(index);
                else
                    trace("Error removing selected non proxied item");
            }
        }

        protected function handleItemSelected(event:PickFilterGridEvent):void {

            var pickFilterRow:PickFilterRow = event.pickFilterRow;

            updatePickFilterRow(pickFilterRow);

            setDefaultSort();
        }

        public function get selectedColumnDatafield():String {
            return _selectedColumnDatafield;
        }

        public function set selectedColumnDatafield(value:String):void {
            _selectedColumnDatafield = value;
        }

        public function get preSelectedIndices():ArrayCollection {
            return _preSelectedIndices;
        }

        public function set preSelectedIndices(value:ArrayCollection):void {
            _preSelectedIndices = value;
            bPreSelectedIndicesChanged = true;
            invalidateProperties();
        }

        public function toggleSelectDeselectAll():void
        {
            var i:int = dataProvider.length;
            var indicesToSelect:ArrayCollection = new ArrayCollection();

            for (var j:int = 0; j < i;j++)
            {
                indicesToSelect.addItem(j);
            }
            _selected = !_selected;
            this.preSelectedIndices = indicesToSelect;
        }

        public function get applyDefaultSort():Boolean {
            return _applyDefaultSort;
        }

        public function set applyDefaultSort(value:Boolean):void {
            _applyDefaultSort = value;
        }

        public function get enabledSelectAll():Boolean {
            return _enabledSelectAll;
        }

        public function set enabledSelectAll(value:Boolean):void {
            _enabledSelectAll = value;
        }

        public function get selected():Boolean {
            return _selected;
        }

    }
}